import { ElMessage, ElMessageBox } from 'element-plus'
import apiMod from '@/apiMod/index'
import { useCommonStore } from '@/stores/common'
import { useCrudStore } from '@/stores/crud'
import { getStore } from '@/utils/store'
import { isNewVersion } from '@/utils/version'

export const useCrud: any = ({
	api,
	loadOrgInfo,
	pageName,
	rowKey,
	dictcodes,
	tipLabel,
	paramsObj,
	defaultTableData,
	operateBefore,
	saveFormate,
	operateFormate,
	beforeOnLoadFormate,
	onLoadFormate,
	searchConfig,
}) => {
	const { getDictList, setMoreSearch, setSearchMode, setGloabnowRowData } = useCommonStore()
	const { queryObj, moreSearchInfo, searchMode } = storeToRefs(useCommonStore())
	const { setTableLoading } = useCrudStore()
	const userInfo = getStore('userInfo') || {}

	const visibleForm = ref(false)
	const dialogTitle = ref('操作')
	const nowRowData: any = ref({})
	const tableData = ref([])
	const searchModel = ref({})
	const whickComm = ref()
	const reloadTable = ref(0)
	const searchFormateMod = ref({})
	let pageReac = ref({
		total: 0,
		size: ['view_dpServiceOrgBaseAndBuilding_page'].includes(api?.index) ? 8 : 10,
		current: 1,
	})
	const multipleSelection = ref([])
	const handleSelectionChange = (arr) => {
		multipleSelection.value = arr
	}
	const handleCancelSelect = () => {
		multipleSelection.value = []
	}

	const getInitData = async (params?: Object, type?) => {
		// 打开加载
		setTableLoading(true)
		if (api?.index && apiMod[api.index]) {
			let searchDefault = {}
			// 获取查询中的默认值
			if (searchConfig?.column) {
				searchConfig.column.forEach((item) => {
					if (item.defaultValue) searchDefault[item.prop] = item.defaultValue
				})
			}

			try {
				if (!paramsObj) {
					paramsObj = {}
				}
				if (api.authArea) {
					paramsObj['authProvince'] = userInfo.authProvince
					paramsObj['authCity'] = userInfo.authCity
					paramsObj['authArea'] = userInfo.authArea
					paramsObj['authStreet'] = userInfo.authStreet
					paramsObj['authCommunity'] = userInfo.authCommunity
				}

				for (let item in paramsObj) {
					if (typeof paramsObj[item] === 'undefined' || paramsObj[item] === null || paramsObj[item] === '') {
						delete paramsObj[item]
					}
				}
				const query = {
					...searchDefault,
					...queryObj.value,
					...pageReac.value,
					...searchModel.value,
					...params,
					...(moreSearchInfo.value?.params || {}),
					...paramsObj,
					pageParaPO: {
						...pageReac.value,
					},
					belongProjectLabel: undefined,
					total: undefined,
					subprojectName: undefined,
				}
				const paramsQuery = beforeOnLoadFormate ? await beforeOnLoadFormate(query, searchModel.value) : query
				searchFormateMod.value = paramsQuery

				if (api.isWithAuth) {
					paramsQuery['isWithAuth'] = 0
				}

				let data: any = null
				if (type && type == 'more') {
					let res = await apiMod[api.moreSearch](paramsQuery)
					data = res.data
				}
				if (type && type == 'reserve') {
					let res = await apiMod[api.reserveSearch](paramsQuery)
					data = res.data
				}
				if (!type || JSON.stringify(type) == '{}') {
					const promiseList = [apiMod[api.index](paramsQuery), api.count ? apiMod[api.count](paramsQuery) : undefined].filter(Boolean)
					data = await Promise.all(promiseList).then((res) => {
						const data0 = res[0]?.data
						const tempObj = {
							...(data0 || {}),
						}
						const total = res[1]?.data
						if (total) {
							tempObj.total = total
						}
						return Array.isArray(data0) ? data0 : tempObj
					})
				}
				// 关闭加载
				setTableLoading(false)
				const listData = Array.isArray(data) ? data : data.records
				const dataList = onLoadFormate ? await onLoadFormate(listData, data) : listData
				tableData.value = dataList
				if (data.total) {
					pageReac.value.total = data.total
					pageReac.value.current = data.current
				} else {
					pageReac.value.total = 0
				}
			} catch (e) {
				// 关闭加载
				setTableLoading(false)
			}
		} else {
			tableData.value = defaultTableData || []
			console.log('默认', defaultTableData)
			// 关闭加载
			setTableLoading(false)
		}
	}
	const refreshChange = (params: Object, visible?: boolean) => {
		reloadTable.value = Math.random()
		visibleForm.value = false
		setGloabnowRowData({})
		if (visible !== undefined) {
			visibleForm.value = visible
		}
		getInitData(params, searchMode.value)
	}

	const handleOperate = async (type: string | number, row: any, titles: string) => {
		isNewVersion()
		try {
			let tempObj = Object.assign({}, row || {})
			if (operateBefore) {
				tempObj = await operateBefore(row, type)
			}
			let lastStr = (str) => str && str.substring(str.length - 4)

			dialogTitle.value = pageName + '-' + titles
			whickComm.value = type
			// (type == 'detail' || type == 'edit') &&
			if (
				api.detail &&
				type != 'delete' &&
				row.id &&
				(lastStr(api.detail).includes('view') || lastStr(api.detail).includes('id') || api.detail.includes('detail'))
			) {
				const detailData = await apiMod[api.detail](api.rowKey ? row[api.rowKey] : row.id)
				tempObj = detailData.data || row
			}
			const res = operateFormate ? await operateFormate(tempObj, type) : tempObj
			if (type == 'refresh') {
				getInitData({}, searchMode.value)
				return
			}
			nowRowData.value = res
			visibleForm.value = false
			setGloabnowRowData({})
			switch (type) {
				case 'delete':
					if (queryObj.value.belongProject && !queryObj.value.subprojectId) {
						ElMessage.warning('请先选择切换项目!')
						return
					} else if (queryObj.value.projectStatus == 0) {
						ElMessage.warning('项目已停用或已到期结束!')
						return
					} else {
						onDel(row)
					}
					break
				default:
					if (queryObj.value.belongProject && !queryObj.value.subprojectId) {
						ElMessage.warning('请先选择切换项目!')
						return
					} else if (queryObj.value.projectStatus == 0 && !['viewCode','detail', 'Archives'].includes(type)) {
						ElMessage.warning('项目已停用或已到期结束!')
						return
					}
					visibleForm.value = !visibleForm.value
					break
			}
		} catch (error) {}
	}
	const onPageChange = (page) => {
		pageReac.value = page
		getInitData({}, searchMode.value)
	}
	// type类型，用于判断是普通搜索还是全字段还是，反向搜索
	const onSearch = (search, done?: any, type?) => {
		// 进行搜索时需要将页码设置为1
		pageReac.value.current = 1
		searchModel.value = search || {}
		// 需要一个数据仓库存一下搜索模式普通，全字段，还是反向全字段
		if (type) setSearchMode(type)
		getInitData({}, searchMode.value)
		done && done()
	}

	const onDel = (row: any) => {
		let title = ''
		if (Array.isArray(row)) {
			title = row[0][tipLabel] + '等' + row.length + '条'
		} else {
			title = row[tipLabel]
		}
		ElMessageBox.confirm(`请确实是否要删除【${title}】的数据?`, '提示', {
			confirmButtonText: '确定',
			cancelButtonText: '取消',
			type: 'warning',
		})
			.then(() => {
				if (api.delete && apiMod[api.delete]) {
					let query = {}
					if (Array.isArray(row)) {
						query = row.map((item) => {
							return item[rowKey]
						})
					} else {
						query = [row[rowKey]]
					}
					apiMod[api.delete](query, row).then(() => {
						ElMessage({
							type: 'success',
							message: '删除成功',
						})
						handleCancelSelect()
						setMoreSearch({})
						refreshChange({})
					})
				} else {
					ElMessage({
						type: 'warning',
						message: '请检查请求接口地址是否正确',
					})
				}
			})
			.catch(() => {})
	}

	const onSubmit = (form, done) => {
		let baseApi = form[rowKey] ? api.edit : api.add
		if (api[whickComm.value] && apiMod[api[whickComm.value]]) {
			baseApi = api[whickComm.value]
		}

		const requestData = (data, modelName) => {
			if (modelName && apiMod[modelName]) {
				for (let item in paramsObj) {
					if (typeof paramsObj[item] === 'undefined' || paramsObj[item] === null || paramsObj[item] === '') {
						delete paramsObj[item]
					}
				}

				apiMod[modelName]({ ...queryObj.value, ...data, ...paramsObj, apiName: undefined })
					.then(() => {
						ElMessage({
							type: 'success',
							message: '操作成功',
						})
						refreshChange({})
						done && done()
					})
					.catch(() => {
						done && done()
					})
			} else {
				ElMessage({
					type: 'warning',
					message: '请检查请求接口地址是否正确',
				})
				done && done()
			}
		}

		if (loadOrgInfo) {
			const orgInfo = getStore('organizationInfo') || {}
			form.provinceId = orgInfo.provinceId
			form.provinceName = orgInfo.provinceName
			form.cityId = orgInfo.cityId
			form.cityName = orgInfo.cityName
			form.areaId = orgInfo.areaId
			form.areaName = orgInfo.areaName
			form.streetId = orgInfo.streetId
			form.streetName = orgInfo.streetName
			form.communityId = orgInfo.communityId
			form.communityName = orgInfo.communityName
			form.creditCode = orgInfo.creditCode
			form.organizationId = orgInfo.organizationId
			form.organizationName = orgInfo.organizationName
		}

		if (saveFormate) {
			saveFormate(form, whickComm.value)
				.then((res: any, apiName?: String) => {
					if (apiName || res.apiName) {
						baseApi = apiName || res.apiName
					}
					requestData(res, baseApi)
				})
				.catch(() => {
					done && done()
				})
		} else {
			requestData(form, baseApi)
		}
	}
	const hanleOpenDialog = () => {
		getDictList(dictcodes)
	}
	onMounted(async () => {
		await getDictList(dictcodes)
		getInitData()
	})

	return {
		reloadTable,
		multipleSelection,
		nowRowData,
		dialogTitle,
		visibleForm,
		tableData,
		pageReac,
		whickComm,
		searchFormateMod,
		setMoreSearch,
		getInitData,
		refreshChange,
		onPageChange,
		onSearch,
		onSubmit,
		handleOperate,
		hanleOpenDialog,
		handleSelectionChange,
		handleCancelSelect,
	}
}

export const useConfig = () => {
	const userInfo = getStore('userInfo') || {}

	const getAreaLevel = () => {
		const areaStr = {
			0: 'province',
			1: 'city',
			2: 'area',
			3: 'street',
			4: 'community',
		}

		const areaLen = [userInfo.authProvince, userInfo.authCity, userInfo.authArea, userInfo.authStreet, userInfo.authCommunity].filter(Boolean)
		const countryLevelList = areaLen.map((_, index) => {
			return index + 1
		})
		countryLevelList.push(countryLevelList.length + 1)
		const areaLevel = areaStr[areaLen.length] || 'org'
		return {
			region: areaLen[areaLen.length] || userInfo.authCommunity,
			areaStr,
			areaLevel,
			areaLen,
			countryLevelList,
			nextAreaLevel: areaStr[areaLen.length + 1],
		}
	}
	return {
		getAreaLevel,
	}
}
